home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Ebooks / Thinking in C++ V2 / C20 / SequencePerformance.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  5.3 KB  |  191 lines

  1. //: C20:SequencePerformance.cpp
  2. // From Thinking in C++, 2nd Edition
  3. // Available at http://www.BruceEckel.com
  4. // (c) Bruce Eckel 1999
  5. // Copyright notice in Copyright.txt
  6. // Comparing the performance of the basic
  7. // sequence containers for various operations
  8. #include <vector>
  9. #include <queue>
  10. #include <list>
  11. #include <iostream>
  12. #include <string>
  13. #include <typeinfo>
  14. #include <ctime>
  15. #include <cstdlib>
  16. using namespace std;
  17.  
  18. class FixedSize {
  19.   int x[20];
  20.   // Automatic generation of default constructor,
  21.   // copy-constructor and operator=
  22. } fs;
  23.  
  24. template<class Cont>
  25. struct InsertBack {
  26.   void operator()(Cont& c, long count) {
  27.     for(long i = 0; i < count; i++)
  28.       c.push_back(fs);
  29.   }
  30.   char* testName() { return "InsertBack"; }
  31. };
  32.  
  33. template<class Cont>
  34. struct InsertFront {
  35.   void operator()(Cont& c, long count) {
  36.     long cnt = count * 10;
  37.     for(long i = 0; i < cnt; i++)
  38.       c.push_front(fs);
  39.   }  
  40.   char* testName() { return "InsertFront"; }
  41. };
  42.  
  43. template<class Cont>
  44. struct InsertMiddle {
  45.   void operator()(Cont& c, long count) {
  46.     typename Cont::iterator it;
  47.     long cnt = count / 10;
  48.     for(long i = 0; i < cnt; i++) {
  49.       // Must get the iterator every time to keep
  50.       // from causing an access violation with
  51.       // vector. Increment it to put it in the
  52.       // middle of the container:
  53.       it = c.begin();
  54.       it++;
  55.       c.insert(it, fs);
  56.     }
  57.   }
  58.   char* testName() { return "InsertMiddle"; }
  59. };
  60.  
  61. template<class Cont>
  62. struct RandomAccess { // Not for list
  63.   void operator()(Cont& c, long count) {
  64.     int sz = c.size();
  65.     long cnt = count * 100;
  66.     for(long i = 0; i < cnt; i++)
  67.       c[rand() % sz];
  68.   }
  69.   char* testName() { return "RandomAccess"; }
  70. };
  71.  
  72. template<class Cont>
  73. struct Traversal {
  74.   void operator()(Cont& c, long count) {
  75.     long cnt = count / 100;
  76.     for(long i = 0; i < cnt; i++) {
  77.       typename Cont::iterator it = c.begin(),
  78.         end = c.end();
  79.       while(it != end) it++;
  80.     }
  81.   }
  82.   char* testName() { return "Traversal"; }
  83. };
  84.  
  85. template<class Cont>
  86. struct Swap {
  87.   void operator()(Cont& c, long count) {
  88.     int middle = c.size() / 2;
  89.     typename Cont::iterator it = c.begin(), 
  90.       mid = c.begin();
  91.     it++; // Put it in the middle
  92.     for(int x = 0; x < middle + 1; x++)
  93.       mid++;
  94.     long cnt = count * 10;
  95.     for(long i = 0; i < cnt; i++)
  96.       swap(*it, *mid);
  97.   }
  98.   char* testName() { return "Swap"; }
  99. };
  100.  
  101. template<class Cont>
  102. struct RemoveMiddle {
  103.   void operator()(Cont& c, long count) {
  104.     long cnt = count / 10;
  105.     if(cnt > c.size()) {
  106.       cout << "RemoveMiddle: not enough elements"
  107.         << endl;
  108.       return;
  109.     }
  110.     for(long i = 0; i < cnt; i++) {
  111.       typename Cont::iterator it = c.begin();
  112.       it++;
  113.       c.erase(it);
  114.     }
  115.   }
  116.   char* testName() { return "RemoveMiddle"; }
  117. };
  118.  
  119. template<class Cont>
  120. struct RemoveBack {
  121.   void operator()(Cont& c, long count) {
  122.     long cnt = count * 10;
  123.     if(cnt > c.size()) {
  124.       cout << "RemoveBack: not enough elements"
  125.         << endl;
  126.       return;
  127.     }
  128.     for(long i = 0; i < cnt; i++)
  129.       c.pop_back();
  130.   }
  131.   char* testName() { return "RemoveBack"; }
  132. };
  133.  
  134. template<class Op, class Container>
  135. void measureTime(Op f, Container& c, long count){
  136.   string id(typeid(f).name());
  137.   bool Deque = id.find("deque") != string::npos;
  138.   bool List = id.find("list") != string::npos;
  139.   bool Vector = id.find("vector") !=string::npos;
  140.   string cont = Deque ? "deque" : List ? "list" 
  141.     : Vector? "vector" : "unknown";
  142.   cout << f.testName() << " for " << cont << ": ";
  143.   // Standard C library CPU ticks:
  144.   clock_t ticks = clock();
  145.   f(c, count); // Run the test
  146.   ticks = clock() - ticks;
  147.   cout << ticks << endl;
  148. }
  149.  
  150. typedef deque<FixedSize> DF;
  151. typedef list<FixedSize> LF;
  152. typedef vector<FixedSize> VF;
  153.  
  154. int main(int argc, char* argv[]) {
  155.   srand(time(0));
  156.   long count = 1000;
  157.   if(argc >= 2) count = atoi(argv[1]);
  158.   DF deq;
  159.   LF lst;
  160.   VF vec, vecres;
  161.   vecres.reserve(count); // Preallocate storage
  162.   measureTime(InsertBack<VF>(), vec, count);
  163.   measureTime(InsertBack<VF>(), vecres, count);
  164.   measureTime(InsertBack<DF>(), deq, count);
  165.   measureTime(InsertBack<LF>(), lst, count);
  166.   // Can't push_front() with a vector:
  167. //! measureTime(InsertFront<VF>(), vec, count);
  168.   measureTime(InsertFront<DF>(), deq, count);
  169.   measureTime(InsertFront<LF>(), lst, count);
  170.   measureTime(InsertMiddle<VF>(), vec, count);
  171.   measureTime(InsertMiddle<DF>(), deq, count);
  172.   measureTime(InsertMiddle<LF>(), lst, count);
  173.   measureTime(RandomAccess<VF>(), vec, count);
  174.   measureTime(RandomAccess<DF>(), deq, count);
  175.   // Can't operator[] with a list:
  176. //! measureTime(RandomAccess<LF>(), lst, count);
  177.   measureTime(Traversal<VF>(), vec, count);
  178.   measureTime(Traversal<DF>(), deq, count);
  179.   measureTime(Traversal<LF>(), lst, count);
  180.   measureTime(Swap<VF>(), vec, count);
  181.   measureTime(Swap<DF>(), deq, count);
  182.   measureTime(Swap<LF>(), lst, count);
  183.   measureTime(RemoveMiddle<VF>(), vec, count);
  184.   measureTime(RemoveMiddle<DF>(), deq, count);
  185.   measureTime(RemoveMiddle<LF>(), lst, count);
  186.   vec.resize(vec.size() * 10); // Make it bigger
  187.   measureTime(RemoveBack<VF>(), vec, count);
  188.   measureTime(RemoveBack<DF>(), deq, count);
  189.   measureTime(RemoveBack<LF>(), lst, count);
  190. } ///:~
  191.